#include "oftree.h"
#include "rtas.h"
+#undef DEBUG
+#ifdef DEBUG
+#define DBG(fmt...) printk(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
+ * page_info table and allocation bitmap.
+ */
+static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
+integer_param("xenheap_megabytes", opt_xenheap_megabytes);
+
unsigned long xenheap_phys_end;
+static uint nr_pages;
+static ulong xenheap_size;
+static ulong save_start;
+static ulong save_end;
+
struct membuf {
ulong start;
ulong size;
static ulong free_xenheap(ulong start, ulong end)
{
- ulong save_start;
- ulong save_end;
-
start = ALIGN_UP(start, PAGE_SIZE);
end = ALIGN_DOWN(end, PAGE_SIZE);
- printk("%s: 0x%lx - 0x%lx\n", __func__, start, end);
-
- save_start = oftree;
- save_end = oftree_end;
- if (rtas_base) {
- if (save_start > rtas_base)
- save_start = rtas_base;
- if (save_end < rtas_end)
- save_end = rtas_end;
- }
+ DBG("%s: 0x%lx - 0x%lx\n", __func__, start, end);
/* need to do this better */
if (save_start <= end && save_start >= start) {
- printk("%s: Go around the saved area: 0x%lx - 0x%lx\n",
+ DBG("%s: Go around the saved area: 0x%lx - 0x%lx\n",
__func__, save_start, save_end);
init_xenheap_pages(start, ALIGN_DOWN(save_start, PAGE_SIZE));
+ xenheap_size += ALIGN_DOWN(save_start, PAGE_SIZE) - start;
+
init_xenheap_pages(ALIGN_UP(save_end, PAGE_SIZE), end);
+ xenheap_size += end - ALIGN_UP(save_end, PAGE_SIZE);
} else {
init_xenheap_pages(start, end);
+ xenheap_size += end - start;
}
return ALIGN_UP(end, PAGE_SIZE);
for (i = 0; i < entries; i++) {
ulong end_page;
- end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT;
+ printk(" %016lx: %016lx\n", mb[i].start, mb[i].size);
+ nr_pages += mb[i].size >> PAGE_SHIFT;
+ end_page = (mb[i].start + mb[i].size) >> PAGE_SHIFT;
if (end_page > max_page)
max_page = end_page;
}
void memory_init(module_t *mod, int mcount)
{
ulong eomem;
- ulong heap_start, heap_size;
-
- printk("Physical RAM map:\n");
+ ulong heap_start;
+ ulong xh_pages;
/* lets find out how much memory there is and set max_page */
max_page = 0;
+ printk("Physical RAM map:\n");
ofd_walk_mem((void *)oftree, set_max_page);
eomem = max_page << PAGE_SHIFT;
if (eomem == 0){
panic("ofd_walk_mem() failed\n");
}
- printk("End of RAM: %luMB (%lukB)\n", eomem >> 20, eomem >> 10);
+
+ /* find the portion of memory we need to keep safe */
+ save_start = oftree;
+ save_end = oftree_end;
+ if (rtas_base) {
+ if (save_start > rtas_base)
+ save_start = rtas_base;
+ if (save_end < rtas_end)
+ save_end = rtas_end;
+ }
+
+ /* minimum heap has to reach to the end of all Xen required memory */
+ xh_pages = ALIGN_UP(save_end, PAGE_SIZE) >> PAGE_SHIFT;
+ xh_pages += opt_xenheap_megabytes << (20 - PAGE_SHIFT);
+
+ /* While we are allocating HTABS from The Xen Heap we need it to
+ * be larger */
+ xh_pages += nr_pages >> 5;
+
+ xenheap_phys_end = xh_pages << PAGE_SHIFT;
+ printk("End of Xen Area: %luMiB (%luKiB)\n",
+ xenheap_phys_end >> 20, xenheap_phys_end >> 10);
+
+ printk("End of RAM: %luMiB (%luKiB)\n", eomem >> 20, eomem >> 10);
/* Architecturally the first 4 pages are exception hendlers, we
* will also be copying down some code there */
panic("total_pages > max_page: 0x%lx > 0x%lx\n",
total_pages, max_page);
- printk("total_pages: 0x%016lx\n", total_pages);
+ DBG("total_pages: 0x%016lx\n", total_pages);
init_frametable();
end_boot_allocator();
/* Add memory between the beginning of the heap and the beginning
- * of out text */
+ * of our text */
free_xenheap(heap_start, (ulong)_start);
-
- heap_size = xenheap_phys_end - heap_start;
- printk("Xen heap: %luMB (%lukB)\n", heap_size >> 20, heap_size >> 10);
-
setup_xenheap(mod, mcount);
+ printk("Xen Heap: %luMiB (%luKiB)\n",
+ xenheap_size >> 20, xenheap_size >> 10);
eomem = avail_domheap_pages();
- printk("Domheap pages: 0x%lx %luMB (%lukB)\n", eomem,
+ printk("Dom Heap: %luMiB (%luKiB)\n",
(eomem << PAGE_SHIFT) >> 20,
(eomem << PAGE_SHIFT) >> 10);
}